#!/usr/bin/env python
###
 #  Primitive trading shell implementation
 # 
 #  (c) 2007, dmitry.ema@gmail.com
 #
import httplib2, sys, cmd
from UserString      import UserString
from optparse        import OptionParser
from FxClubWebDriver import *
from Structures      import *

CONFIG_FILE="trshell.cfg"

# Load configuration file and read it
# returns hash of {'option':'value'}
def loadConfig(cfgName):
  cfg = {}
  f = file(cfgName)
  for s in f.readlines():
	u = UserString(s).strip()
	if u.startswith('#'): continue
	p = u.split('=')
	if len(p) < 2: continue
	cfg[p[0].strip()] = p[1].strip()
  f.close()
  return cfg

## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # Ineractive command shell
 #
class TraiderShell(cmd.Cmd):
  
  def __init__(this,mode,noLogin=False):
	cmd.Cmd.__init__(this)
	this.prompt = "%s-> %s" % (WHITE,GRAY)
	try: 
	  # load configuration file
	  cfg = loadConfig(CONFIG_FILE)
	  prx = cfg['use proxy'].upper()
	  psrv = cfg['proxy']
	  pport = cfg['port']
	except Exception,e:
	  print "Error reading ",CONFIG_FILE,' ',e
	  sys.exit()

	# check for proxy
	if prx!=None and (prx=='1' or prx=='TRUE'):
	  if psrv==None: psrv='localhost'
	  if pport==None: port=8080
	  this.drv = FxClubWebDriver(isDbg=True,isLocal=mode,useProxy=True,proxyServer=psrv,proxyPort=int(pport))
	else:
	  this.drv = FxClubWebDriver(isDbg=True,isLocal=mode)

	# we aren't logged in initialy
	this.isLoggedIn = False
	this._log = ''
	this._pas = ''

	# check for autologin
	if (not noLogin) and cfg.has_key('enable autologin'):
	  _t = cfg['enable autologin'].upper() 
	  if _t!=None and (_t=='1' or _t=='TRUE'):
		if cfg.has_key('login') and cfg.has_key('password'):
		  this.do_login("%s %s" % (cfg['login'],cfg['password']))

	# local vars initialize
	this.currPoses = []      # current open positions 
	this.quotes = {}         # current quotes

		  
  # prevent from repeating last command on empty line input
  def emptyline(this): pass


  # asks a question
  def asksQuestion(this,quest):
	print quest,' (yes/no) ',
	s=sys.stdin.readline().upper().strip()
	if s == 'Y' or s == 'YES': return True
	return False

  
  def getArgs(this,a):
	p = map(string.strip,a.split())
	return len(p), p

  
  def checkLogin(this):
	if not this.isLoggedIn:
	  print "You are not logged in, operation isn't permitted"
	  return False
	return True

  
  def do_exit(this,a):
	this.do_logout(None)
	sys.exit()

	
  def do_quit(this,a): this.do_exit(None)

  
  #-- relogin command
  def do_relogin(this,a):
	if not this.checkLogin(): return
	this.do_logout('')
	if this._log != '' and this._pas != '':
	  this.do_login(this._log + ' ' + this._pas)
	
  
  #-- logout from here
  def do_logout(this,a):
	if not this.checkLogin(): return
	this.drv.logout()
	this.isLoggedIn = False

	
  #-- login command
  def do_login(this,a):
	n,args = this.getArgs(a)
	if n < 2:
	  print "Wrong number of arguments: using: login account password"
	  return
	if this.isLoggedIn:
	  print "You are already logged in, multiaccounts are not suported yet !"
	  return
	if this.drv.login(args[0],args[1]) == False:
	  print "Login failed"
	  return
	print "Account '%s' is logged in" % args[0]
	this.isLoggedIn = True
	this._log = args[0]
	this._pas = args[1]

	
  #-- get current information
  def do_info(this,a):
	if not this.checkLogin(): return
	b = this.drv.getBalance()
	a = this.drv.getAccount()
	print "[",a,"] BALANCE: ",b

	
  #-- list open positions
  def do_lp(this,a): 
	if not this.checkLogin(): return
	print '\tNum\tTool\tLot\tProfit (pips)\tOpen price'
	this.currPoses = []
	this.currPoses = this.drv.getPositions()
	for i in this.currPoses:
	  if i.pProfit < 0:
		print RED,
	  else:
		print GREEN,
	  print '\t',i.toString()
	print GRAY,

	
  #-- list orders
  def do_lo(this,a):
	if not this.checkLogin(): return
	orders = this.drv.getOrders()
	if len(orders) <= 0: return
	for i in orders:
	  color = GRAY
	  if i.state=='inactive': color = BROWN
	  print '\t',color,i.toString(),GRAY

	  
  #-- list quotes
  def do_lq(this,a):
	r = this.drv.getQuotes()
	x = 0
	keys = r.keys()
	keys.sort()
	for i in keys:
	  bid = r[i][0]
	  ask = r[i][1]
	  cl1 = ''
	  
	  # check for state
	  if this.quotes.has_key(i):
		pBid = float(this.quotes[i][0])
		pState = this.quotes[i][2]

		if float(bid) == pBid: cl1 = pState
		if float(bid) > pBid: cl1 = GREEN
		if float(bid) < pBid: cl1 = RED
		r[i][2] = cl1

	  print WHITE,i," : ",cl1,bid," / ",cl1,ask,GRAY,
	  if x % 2:	print
	  x += 1
	print
	this.quotes = r
		

	  
  #-- try to sell
  def do_sell(this,a):
	if not this.checkLogin(): return
	n,args = this.getArgs(a)
	if n < 2:
	  print "Wrong number of arguments: usage: sell tool lot"
	  return
	lot = float(args[1])
	if lot>=1000: lot = float(lot)/1000000.0
	this.drv.doSell(args[0],lot)

	
  #-- try to buy
  def do_buy(this,a):
	if not this.checkLogin(): return
	n,args = this.getArgs(a)
	if n < 2:
	  print "Wrong number of arguments: usage: buy tool lot"
	  return
	lot = float(args[1])
	if lot>=1000: lot = float(lot)/1000000.0
	this.drv.doBuy(args[0],lot)


  #-- close position by it's number
  # must be executed after lp command
  def do_x(this,a):
	if not this.checkLogin(): return
	n,args = this.getArgs(a)
	if n < 1:
	  print "Wrong number of arguments: usage: x numpos"
	  return
	l = len(this.currPoses)
	n = int(args[0]) - 1
	if l==0:
	  print "There aren't any open positions to close. Try to run 'lp' command"
	  return
	if n > l-1 or n < 0:
	  print "Wrong index"
	  return
	p = this.currPoses[n]
	dStr = p.tool.getCanonicalName() + ' ' + str(abs(p.lot))
	if p.lot < 0:
	  print 'You should buy ',dStr,
	  if this.asksQuestion("Are you agree ?"): this.do_buy(dStr)
	else:
	  print 'You should sell ',dStr,
	  if this.asksQuestion("Are you agree ?"): this.do_sell(dStr)



# Main entry point
def main():
  parser = OptionParser()
  parser.add_option("-t","--test", action = "store_true", default=False, dest="t",
 					help="in test mode any server response will be taken from the 'local' directory")
  parser.add_option("-N","--nologin", action = "store_true", default=False, dest="n",
 					help="doesn't use autologin option if set")
  (z,args) = parser.parse_args()

#   import httplib2
#   h = httplib2.Http()
#   r,c = h.request("http://localhost/cgi-bin/cook.pl",'GET')
#   print r, "\n-----------------------------------------"
#   print c, "\n-----------------------------------------"
  
#   if r.has_key('set-cookie'):
# 	cookie = {'Cookie': r['set-cookie']}
# 	print cookie

#   r,c = h.request("http://localhost/cgi-bin/cook.pl",'GET')
#   print r, "\n-----------------------------------------"
#   print c, "\n-----------------------------------------"
  
  # start shell
  tshell = TraiderShell(z.t,noLogin=z.n)
  tshell.cmdloop()
  
if __name__=="__main__": main()
